/*
* Copyright 2018, 2019, 2020 Dooboolab.
*
* This file is part of Flutter-Sound.
*
* Flutter-Sound is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 (LGPL-V3), as published by
* the Free Software Foundation.
*
* Flutter-Sound is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Flutter-Sound.  If not, see <https://www.gnu.org/licenses/>.
*/


import 'package:flutter/material.dart';
import 'dart:async';

// stt
import 'dart:math';
import 'package:speech_to_text/speech_recognition_error.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart';

/*
 * This is an example showing how to do Speech To Text.
 * This is just for FUN :-D, because this example does not use the Flutter Sound library.
 * But it is included in Flutter Sound examples because it shows how easy it is
 * to deal with Sounds on Flutter, even without Flutter Sound.
 *
 * This example was provided by @jtkeyva. Thanks to him :-)
 *
 */

/// Example app.
class SpeechToTextExample extends StatefulWidget {
@override
_SpeechToTextExampleState createState() => _SpeechToTextExampleState();
}

class _SpeechToTextExampleState extends State {

  // STT
  bool _hasSpeech = false;
  double level = 0.0;
  double minSoundLevel = 50000;
  double maxSoundLevel = -50000;
  String lastWords = "";
  String lastError = "";
  String lastStatus = "";
  String _currentLocaleId = "";
  List<LocaleName> _localeNames = [];
  final SpeechToText speech = SpeechToText();

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();

  }

  // stt
  Future initSpeechState() async {
  bool hasSpeech = await speech.initialize(
  onError: errorListener, onStatus: statusListener);
  if (hasSpeech) {
    _localeNames = await speech.locales();

    var systemLocale = await speech.systemLocale();
    _currentLocaleId = systemLocale.localeId;
  }

  if (!mounted) return;

  setState(() {
    _hasSpeech = hasSpeech;
  });

  }


  // ----------------------------------------------------------------------------------------------------------------------

  @override
  Widget build(BuildContext context) {

  Widget makeBody()
  {
    DropdownMenuItem<String> items(LocaleName localeName)
    {
      DropdownMenuItem<String> r = DropdownMenuItem<String>(
        value: localeName.localeId,
        child: Text(localeName.name),
      );
      return r;
    }

    return Column( children:[

      Container(
          child: Column(
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  FlatButton(
                    child: Text('Initialize'),
                    onPressed: _hasSpeech ? null : initSpeechState,
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  FlatButton(
                    child: Text('Start'),
                    onPressed: !_hasSpeech || speech.isListening
                        ? null
                        : startListening,
                  ),
                  FlatButton(
                    child: Text('Stop'),
                    onPressed: speech.isListening ? stopListening : null,
                  ),
                  FlatButton(
                    child: Text('Cancel'),
                    onPressed: speech.isListening ? cancelListening : null,
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  DropdownButton<String>(
                    onChanged: (String selectedVal) => _switchLang(selectedVal),
                    value: _currentLocaleId,
                    items:  _localeNames.map(items).toList() ,
                  ),
                ],
              )
            ],
          ),
        ),
        Expanded(
          flex: 4,
          child: Column(
            children: <Widget>[
              Center(
                child: Text(
                  'Recognized Words',
                  style: TextStyle(fontSize: 22.0),
                ),
              ),
              Expanded(
                child: Stack(
                  children: <Widget>[
                    Container(
                      color: Theme.of(context).selectedRowColor,
                      child: Center(
                        child: Text(
                          lastWords,
                          textAlign: TextAlign.center,
                        ),
                      ),
                    ),
                    Positioned.fill(
                      bottom: 10,
                      child: Align(
                        alignment: Alignment.bottomCenter,
                        child: Container(
                          width: 40,
                          height: 40,
                          alignment: Alignment.center,
                          decoration: BoxDecoration(
                            boxShadow: [
                              BoxShadow(
                                  blurRadius: .26,
                                  spreadRadius: level * 1.5,
                                  color: Colors.black.withOpacity(.05))
                            ],
                            color: Colors.white,
                            borderRadius:
                                BorderRadius.all(Radius.circular(50)),
                          ),
                          child: IconButton(icon: Icon(Icons.mic)),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
        Expanded(
          flex: 1,
          child: Column(
            children: <Widget>[
              Center(
                child: Text(
                  'Error Status',
                  style: TextStyle(fontSize: 22.0),
                ),
              ),
              Center(
                child: Text(lastError),
              ),
            ],
          ),
        ),
        Container(
          padding: EdgeInsets.symmetric(vertical: 20),
          color: Theme.of(context).backgroundColor,
          child: Center(
            child: speech.isListening
                ? Text(
                    "I'm listening...",
                    style: TextStyle(fontWeight: FontWeight.bold),
                  )
                : Text(
                    'Not listening',
                    style: TextStyle(fontWeight: FontWeight.bold),
                  ),
          ),
        ),

    ],
    );
  }


  return Scaffold(backgroundColor: Colors.blue,
    appBar: AppBar(
      title: const Text('Speech to Text ex.'),
    ),
    body: makeBody(),
  );

  }

  // tts

  void startListening() {
    lastWords = "";
    lastError = "";
    speech.listen(
    onResult: resultListener,
    listenFor: Duration(seconds: 60),
    localeId: _currentLocaleId,
    onSoundLevelChange: soundLevelListener,
    cancelOnError: true,
    listenMode: ListenMode.confirmation);
    setState(() {});
  }

  void stopListening() {
    speech.stop();
    setState(() {
      level = 0.0;
    });
  }

  void cancelListening() {
    speech.cancel();
    setState(() {
      level = 0.0;
    });
  }

  void resultListener(SpeechRecognitionResult result) {
    setState(() {
      lastWords = "${result.recognizedWords} - ${result.finalResult}";
    });
  }

  void soundLevelListener(double level) {
    minSoundLevel = min(minSoundLevel, level);
    maxSoundLevel = max(maxSoundLevel, level);
    // print("sound level $level: $minSoundLevel - $maxSoundLevel ");
    setState(() {
      this.level = level;
    });
  }

  void errorListener(SpeechRecognitionError error) {
    // print("Received error status: $error, listening: ${speech.isListening}");
    setState(() {
      lastError = "${error.errorMsg} - ${error.permanent}";
    });
  }

  void statusListener(String status) {
    // print(
    // "Received listener status: $status, listening: ${speech.isListening}");
    setState(() {
      lastStatus = "$status";
    });
  }

  void _switchLang(String selectedVal)
  {
    setState(() {
    _currentLocaleId = selectedVal;
    });
    print(selectedVal);
  }

}

